package com.suretech.nms.subagent;

import java.util.List;

import org.snmp4j.agent.agentx.subagent.index.AnyNewIndexOID;
import org.snmp4j.agent.mo.DefaultMOMutableRow2PC;
import org.snmp4j.agent.mo.DefaultMOMutableRow2PCFactory;
import org.snmp4j.agent.mo.MOColumn;
import org.snmp4j.agent.mo.MOFactory;
import org.snmp4j.agent.mo.MOMutableColumn;
import org.snmp4j.agent.mo.MOTable;
import org.snmp4j.agent.mo.MOTableIndex;
import org.snmp4j.agent.mo.MOTableIndexValidator;
import org.snmp4j.agent.mo.MOTableRow;
import org.snmp4j.agent.mo.MOTableSubIndex;
import org.snmp4j.agent.mo.NMSMOMutableTableModel;
import org.snmp4j.agent.mo.NMSMOTable;
import org.snmp4j.agent.mo.NMSMOTableModel;
import org.snmp4j.agent.mo.NMSSubagentMOTable;
import org.snmp4j.smi.Integer32;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.SMIConstants;
import org.snmp4j.smi.Variable;

public class AgentTable {

	private NMSMOTable table;
	private OID oid;
	private List<ColumnEntry> columnEntrys;
	private int indexType;
	private AgentTableService agentTableService;

	private NMSMOTableModel tableModel;

	public AgentTable(OID oid, List<ColumnEntry> columnEntrys, int indexType,
			AgentTableService srv) {
		this.oid = oid;
		this.columnEntrys = columnEntrys;
		this.indexType = indexType;
		this.agentTableService = srv;
	}

	public void createAgentEntry(MOFactory moFactory) {
		// Index definition
		OID tableEntry=new OID(oid + ".1");
		MOTableSubIndex[] subIndexes = new MOTableSubIndex[] { moFactory.createSubIndex(new OID(tableEntry + ".1"),
						SMIConstants.SYNTAX_OCTET_STRING, 1, 255) };
		MOTableIndex indexDef = moFactory.createIndex(subIndexes, false,
				new MOTableIndexValidator() {
					public boolean isValidIndex(OID index) {
						boolean isValidIndex = true;
						return isValidIndex;
					}
				});

		// Columns
		MOColumn[] columns = new MOColumn[columnEntrys.size()];
		for (int i = 0; i < columnEntrys.size(); i++) {
			ColumnEntry column = columnEntrys.get(i);
			columns[i] = moFactory.createColumn(i+1, column
					.getColumnType(), moFactory.createAccess(column
					.getColumnAccess()), column.getDefaultValue(), true);
			columns[i].setAgentTableService(agentTableService);
		}
		//table
		table = new NMSSubagentMOTable(tableEntry, indexDef, columns);
		table.setAgentTableService(agentTableService);

		//table model
		tableModel = (NMSMOTableModel) table.getModel();
		tableModel.setAgentTableService(agentTableService);
		((NMSMOMutableTableModel) tableModel).setRowFactory(new AgentEntryRowFactory());
		 
		//table row
//		MOTableRow row = table.createRow(new AnyNewIndexOID(new int[]{1}));
//		table.addRow(row);
		
		for (Variable var = agentTableService.getFirstIndex(); var != null; var = agentTableService.getNextIndex()) {
			MOTableRow row = null;
			if (var instanceof Integer32) {
				row = table.createRow(new AnyNewIndexOID(new int[]{Integer.parseInt(var.toString())}));
			}
			if (var instanceof OctetString) {
				row = table.createRow(new AnyNewIndexOID(var.toString()));
			} 			
			table.addRow(row);
		}
//		Variable[] values=table.getDefaultValues();
//		for (int i = 0; (i < values.length); i++) {
//			if (columns[i] instanceof MOMutableColumn) {
//				values[i] = ((MOMutableColumn) columns[i]).getDefaultValue();
//				System.err.println(values[i].getSyntaxString());
//			}
//		}
		 
		//return service
		agentTableService.setColumnCount(tableModel.getColumnCount());
		agentTableService.setRowCount(tableModel.getRowCount());
	}

	public MOTable getAgentEntry() {
		return table;
	}
}

class AgentEntryRowFactory extends DefaultMOMutableRow2PCFactory {

	public synchronized MOTableRow createRow(OID index, Variable[] values)
			throws UnsupportedOperationException {
//		AgentEntryRow row = new AgentEntryRow(index, values);
//		return row;
		return new DefaultMOMutableRow2PC(index, values);
	}

	public synchronized void freeRow(MOTableRow row) {
	}
}

class AgentEntryRow extends DefaultMOMutableRow2PC {
	public AgentEntryRow(OID index, Variable[] values) {
		super(index, values);
	}

	public void setValue(int column, Variable value) {
		if (value.equals(getValue(column))) {
			super.setValue(column, null);
			return;
		}
		super.setValue(column, value);
	}
}
